#include "MultiThreadWriter.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

MultiThreadWriter* MultiThreadWriter::GetInstance()
{
	static MultiThreadWriter* s_instance = NULL;
	if(s_instance == NULL)
	{
		s_instance = new MultiThreadWriter();
	}
	return s_instance;
}

MultiThreadWriter::MultiThreadWriter()
{
	pthread_mutex_init(&m_mutexQueue, NULL);
	m_tid = 0;
	m_flagExit = false;
}

MultiThreadWriter::~MultiThreadWriter()
{
	pthread_mutex_destroy(&m_mutexQueue);
}

void* MultiThreadWriter::thread_func(void* arg)
{
//	sleep(1);
	pthread_t pid;
	pid = pthread_self();

	std::queue<Thread_Arg>* taskQueue = (std::queue<Thread_Arg>*)arg;
	printf("thread %d: init\n", pid);
	while(MultiThreadWriter::GetInstance()->m_flagExit == false || taskQueue->size() > 0)
	{
		if(taskQueue->size() > 0)
		{
			pthread_mutex_lock(&MultiThreadWriter::GetInstance()->m_mutexQueue);
			Thread_Arg targ = taskQueue->front();
			taskQueue->pop();
			pthread_mutex_unlock(&MultiThreadWriter::GetInstance()->m_mutexQueue);
			
			FILE* handle = NULL;
			handle = fopen(targ.str.c_str(), "wb+");
			printf("thread %d: open file\n", pid);
			if(NULL == handle)
			{
				printf("could not open %s\n", targ.str.c_str());
			}
			fwrite(targ.data, targ.size, 1, handle);
			printf("thread %d: writing %s\n", pid, targ.data);

			free(targ.data);
			printf("thread %d: free data\n", pid);

			fclose(handle);
			printf("thread %d: close file\n\n", pid);
			usleep(1000);
		}
		else
		{
			usleep(10000);
		}
	}
	printf("thread %d: over\n", pid);
}

void MultiThreadWriter::AddTask(char* name, char* data, unsigned size)
{
	Thread_Arg tmp;
	tmp.str = name;
	tmp.data = (char*)malloc(size);
	strncpy(tmp.data, data, size);
	tmp.size = size;

	pthread_mutex_lock(&m_mutexQueue);
	m_threadArgTable.push(tmp);
	pthread_mutex_unlock(&m_mutexQueue);
	if(m_tid == 0)
	{
		pthread_create(&m_tid, NULL, MultiThreadWriter::thread_func, &m_threadArgTable);
	//	pthread_detach(m_tid);
		printf("create thread %d\n", m_tid);
	}
}
